package jp.sourceforge.akjrcp.videotools.imagetomovie;


import java.io.File;

import jp.sourceforge.akjrcp.akj_betas.Akj_betasPlugin;
import jp.sourceforge.akjrcp.akj_betas.Messages;
import jp.sourceforge.akjrcp.commons.ui.FileDirChoicer;
import jp.sourceforge.akjrcp.commons.ui.AbstractFileDirChoicer.FileStatusChangeEvent;
import jp.sourceforge.akjrcp.commons.ui.AbstractFileDirChoicer.FileStatusChangeListener;
import jp.sourceforge.akjrcp.commons.ui.widget.WidgetBuilder;
import jp.sourceforge.akjrcp.dropsomething.DropsomethingView;
import jp.sourceforge.akjrcp.ffmpeg.FFMpegFLVParser;
import jp.sourceforge.akjrcp.ffmpeg.FFMpegFileInfomation;
import jp.sourceforge.akjrcp.ffmpeg.FFMpegInput;
import jp.sourceforge.akjrcp.ffmpeg.FFMpegOptions;
import jp.sourceforge.akjrcp.ffmpeg.FFMpegPreference;
import jp.sourceforge.akjrcp.ffmpeg.FFMpegUI;
import jp.sourceforge.akjrcp.ffmpeg.FFMpegUtils;
import jp.sourceforge.akjrcp.ffmpeg.SimpleCommandExecuter;
import jp.sourceforge.akjrcp.ui.FileOverwriteControler;
import jp.sourceforge.akjrcp.ui.param.ParamCombo;
import jp.sourceforge.akjrcp.util.ExecutingControler;
import jp.sourceforge.akjrcp.util.ExecutingControler.ExecutingControlButton;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.eclipse.jface.action.IStatusLineManager;
import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.ui.IActionBars;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.internal.WorkbenchWindow;
import org.eclipse.ui.part.ViewPart;


public class SingleImageToMovie extends ViewPart {
	public static Log log=LogFactory.getLog(SingleImageToMovie.class);
	
	public static final String ID = SingleImageToMovie.class.getName();

	/**
	 * This is a callback that will allow us to create the viewer and initialize
	 * it.
	 */
	
	Composite composite;

	private FileDirChoicer imageFileChooser;

	private FileDirChoicer audioFileChooser;

	private FileDirChoicer outputFileChooser;

	private SingleImageToMovieExecute singleImageToMovieExecute;

	private ParamCombo aspectRatio;
	
	
	
	
	public void createPartControl(Composite parent) {
		parent.setLayout(new GridLayout(1,false));
		singleImageToMovieExecute = new SingleImageToMovieExecute();
		FileSelected selected=new FileSelected();
		imageFileChooser = new FileDirChoicer(parent,SWT.BORDER,FileDirChoicer.FILE,Messages.getString("singleimagetomovie.imagefile"));
		imageFileChooser.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
		imageFileChooser.setFilterExtensions(new String[]{"*.jpg","*.png","*.avi;*.flv"});//avi is temporary 
		imageFileChooser.addFileListChangeListener(selected);
		
		audioFileChooser = new FileDirChoicer(parent,SWT.BORDER,FileDirChoicer.FILE,Messages.getString("singleimagetomovie.audiofile"));
		audioFileChooser.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
		audioFileChooser.setFilterExtensions(new String[]{"*.mp3;*.flv;*.wav","*.mp3","*.wav","*.flv"});
		audioFileChooser.addFileListChangeListener(selected);
		
		outputFileChooser = new FileDirChoicer(parent,SWT.BORDER,FileDirChoicer.SAVE,Messages.getString("singleimagetomovie.outputfile"));
		outputFileChooser.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
		outputFileChooser.setFilterExtensions(new String[]{"*.avi"});
		outputFileChooser.addFileListChangeListener(selected);
		outputFileChooser.addFileListChangeListener(new OverwriteCheck());
		
		Composite options=WidgetBuilder.createGridLayoutComposite(parent, SWT.NULL,4,false);
		frameRate = new ParamCombo(options,SWT.NONE,"r",Messages.getString("singleimagetomovie.frameRate"),
				new String[]{"","1","5","12","14.895","15","20","24","25","29.97","30"});
		
		aspectRatio = new ParamCombo(options,SWT.NONE,"aspect",Messages.getString("singleimagetomovie.aspect"),
				new String[]{"4:3","16:9"});
		
		singleImageToMovieExecute.addControl(imageFileChooser);
		singleImageToMovieExecute.addControl(audioFileChooser);
		singleImageToMovieExecute.addControl(outputFileChooser);
		
		ExecutingControlButton exec=new ExecutingControlButton(parent,SWT.NULL,singleImageToMovieExecute,
				Messages.getString("singleimagetomovie.exec"),Messages.getString("singleimagetomovie.cancel"));
		
		
		
		
	}
	

	
	public class OverwriteCheck implements FileStatusChangeListener{

		public void addList(FileStatusChangeEvent event) {
			File f=new File(event.getFilePath());
			if(f.exists()){
				FileOverwriteControler controler=new FileOverwriteControler(PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(),FileOverwriteControler.MODE_YES_NO_CANCEL);
				boolean r=controler.canOverwrite(f);
				if(r==false){
					((FileDirChoicer)event.getSource()).removePath();//cancel
				}
			}
		}

		public void removeList(FileStatusChangeEvent event) {
			
		}
		
	}
	
	public class FileSelected implements FileStatusChangeListener{

		public void addList(FileStatusChangeEvent event) {
			
			singleImageToMovieExecute.updateControlSwitch();
		}

		public void removeList(FileStatusChangeEvent event) {
			singleImageToMovieExecute.updateControlSwitch();
		}
		
	}
	
	private String imagePath;
	private String audioPath;
	private String outputPath;

	private ParamCombo frameRate;
	public class SingleImageToMovieExecute extends ExecutingControler{

		private SimpleCommandExecuter simpleExecuter;

		double frameRate_value=1;
		String aspectRatio_value="4:3";
		public void afterExecute() {
			
		}

		public void beforeExecute() {
			if(!frameRate.getValue().equals("")){
				try{
				frameRate_value=Double.parseDouble(frameRate.getValue());
				}catch(Exception e){e.printStackTrace();}
			}
			if(!aspectRatio.getValue().equals("")){
				try{
					aspectRatio_value=aspectRatio.getValue();
				}catch(Exception e){e.printStackTrace();}
			}
			imagePath=imageFileChooser.getAbsoluteFilePath();
			audioPath=audioFileChooser.getAbsoluteFilePath();
			outputPath=outputFileChooser.getAbsoluteFilePath();
		}

		public boolean canExecute() {
			if(!imageFileChooser.getAbsoluteFilePath().equals("")&&!audioFileChooser.getAbsoluteFilePath().equals("")&&!outputFileChooser.getAbsoluteFilePath().equals("")){
				return true;
			}
			return false;
		}

		public void cancelExecuting() {
			simpleExecuter.getProcess().destroy();
		}


		public void inExecute(){
			String ffmpegPath=FFMpegUI.getFFmpeg();
			if(ffmpegPath==null){
				//TODO error
				Akj_betasPlugin.getDefault().getProcessPrinter().printOutput("error:need ffmpeg.exe\n");
				//canceldExecute();
				return;
			}
			
			
			FFMpegPreference preference=new FFMpegPreference();
			preference.setFfmpegPath(ffmpegPath);
			FFMpegInput imageInput;
			
			if(imagePath.toLowerCase().endsWith(".avi") ||imagePath.toLowerCase().endsWith(".flv")){//temporary mux mode
			preference.setVideoCodec(FFMpegOptions.CODEC_COPY);
			imageInput=new FFMpegInput(imagePath);
			
			//set map
			preference.addMap("0:0");//input 
				if(audioPath.toLowerCase().endsWith(".flv")){
					preference.addMap("1:1");//have 2 channel
				}else{
					preference.addMap("1:0");//mp3 has 1 track 
				}
			}else{
			preference.setShortest(true);//TODO support
			preference.setVideoRate(frameRate_value);
			preference.setVideoCodec(FFMpegOptions.CODEC_VIDEO_XVID);
			//preference.setLoop(true);
			//preference.setVideoRate(1);
			preference.setAudioCodec(FFMpegOptions.CODEC_COPY);
			imageInput=new FFMpegInput(imagePath);
			imageInput.setFormat("image2");
			imageInput.setLoop(true);
			
			
			
			
			FFMpegFLVParser parser=new FFMpegFLVParser(ffmpegPath);
			FFMpegFileInfomation imageInfo=parser.parseFile(new File(imagePath));
			//Frame size must be a multiple of 2
			if(imageInfo.getVideoWidth()>0&&imageInfo.getVideoHeight()>0){
				int w=imageInfo.getVideoWidth();
				if(w%2>0){
					w+=1;
				}
				int h=imageInfo.getVideoHeight();
				if(h%2>0){
					h+=1;
				}
				preference.setVideoSize(w,h);
			}
			}
			FFMpegFLVParser parser=new FFMpegFLVParser(ffmpegPath);
			FFMpegFileInfomation imageInfo=parser.parseFile(new File(imagePath));
			FFMpegFileInfomation audioInfo=parser.parseFile(new File(audioPath));
			
			printInputInfo(imageInfo,audioInfo);
			
			preference.setVideoAspect(aspectRatio_value);//for xvid BBUUG
			preference.setVideoBitrate(9000);
			preference.setQmax(1);
			preference.setQmin(1);
			
			preference.setAudioCodec(FFMpegOptions.CODEC_COPY);
			
			String commands[]=preference.toCommand(new FFMpegInput[]{imageInput,new FFMpegInput(audioPath)}, outputPath);
			Akj_betasPlugin.getDefault().getProcessPrinter().printOutput(FFMpegUtils.toPrintCommand(commands));
			simpleExecuter = new SimpleCommandExecuter(commands);
			simpleExecuter.setPrinter(Akj_betasPlugin.getDefault().getProcessPrinter());
			simpleExecuter.execute();
			
			
			
		}
		
	}
	public void printInputInfo(FFMpegFileInfomation imageInfo,FFMpegFileInfomation audioInfo){
		Akj_betasPlugin.getDefault().getProcessPrinter().printOutput("########SingleImageToMovieInupt Info\n");
		Akj_betasPlugin.getDefault().getProcessPrinter().printOutput("####Image\n");
		Akj_betasPlugin.getDefault().getProcessPrinter().printOutput(imageInfo.getText());
		Akj_betasPlugin.getDefault().getProcessPrinter().printOutput("####\n");
		Akj_betasPlugin.getDefault().getProcessPrinter().printOutput("####Audio\n");
		Akj_betasPlugin.getDefault().getProcessPrinter().printOutput(audioInfo.getText());
		Akj_betasPlugin.getDefault().getProcessPrinter().printOutput("####\n");
		Akj_betasPlugin.getDefault().getProcessPrinter().printOutput("########\n");
		//imageInfo.get
	}
	
	
	public void setStatusValue(String value){
		PlatformUI.getWorkbench().getDisplay().asyncExec(new SetMessage(value));
		
	}
	
	public class SetMessage implements Runnable{
		String message;
		SetMessage(String message){
			this.message=message;
		}
		public void run(){
			WorkbenchWindow workbenchWindow =  (WorkbenchWindow) DropsomethingView.viewSite.getWorkbenchWindow();
			IActionBars actionBars = workbenchWindow.getActionBars();
			IStatusLineManager manager = actionBars.getStatusLineManager();
			manager.setMessage(message);
		}
	}
	
	


	
	public void setFocus() {
		// TODO Auto-generated method stub
		
	}
	
}